Skip to content

OCPCLOUD-3451: Scope capi-operator and capi-installer RBAC to least-privilege#607

Open
stefanonardo wants to merge 1 commit into
openshift:mainfrom
stefanonardo:OCPCLOUD-3451
Open

OCPCLOUD-3451: Scope capi-operator and capi-installer RBAC to least-privilege#607
stefanonardo wants to merge 1 commit into
openshift:mainfrom
stefanonardo:OCPCLOUD-3451

Conversation

@stefanonardo

@stefanonardo stefanonardo commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Replace the shared wildcard ClusterRole openshift-capi-operator (apiGroups: ['*'], resources: ['*'], verbs: ['*']) with separate, enumerated RBAC for each ServiceAccount
  • capi-operator gets a narrow ClusterRole (config resources, ClusterOperator management restricted to cluster-api by name) + namespace Roles in openshift-cluster-api-operator (leases, Deployment write, configmaps, pod self-read, events) and openshift-cluster-api (read-only cache informers for deployments and configmaps)
  • capi-installer gets a ClusterRole with get+list */* (needed for VAP binding creation when policies don't exist yet — the API server falls back to checking both get and list on all resources), enumerated write permissions (CRDs, admission resources, cluster RBAC with escalate/bind), and namespace Roles in openshift-cluster-api (boxcutter-managed resources, VAP paramRef), openshift-cluster-api-operator (leases, pod/configmap read), and openshift-machine-api (VAP paramRef list)
  • Derived from static code analysis of all controllers and cross-validated with audit2rbac on a live AWS cluster

Permission justification

Each rule was derived from code analysis and validated against audit2rbac output from an AWS cluster.

capi-operator

Scope API Group Resource Verbs Code evidence
ClusterRole config.openshift.io infrastructures get main.go:104 util.GetInfra()
ClusterRole config.openshift.io clusteroperators get, list, watch, create clusteroperator_controller.go:73, operator_status.go:119
ClusterRole config.openshift.io clusteroperators update, patch operator_status.go:186 (resourceNames: cluster-api)
ClusterRole config.openshift.io clusteroperators/status update, patch operator_status.go:186 (resourceNames: cluster-api)
ClusterRole config.openshift.io clusterversions, featuregates get, list, watch main.go:114 util.GetFeatureGates()
ClusterRole operator.openshift.io clusterapis get, list, watch installerdeployment/controller.go:167
Role: operator ns apps deployments get, list, watch, create, patch, update, delete controller.go:148 SSA, :163 For(), :209 delete
Role: operator ns "" configmaps get, list, watch controller.go:107,166
Role: operator ns "" pods get main.go:158 pod self-read
Role: operator ns "" events create, patch operator_status.go:98
Role: operator ns coordination.k8s.io leases get, list, watch, create, update, patch, delete Leader election
Role: CAPI ns apps deployments get, list, watch DefaultNamespaces cache informer
Role: CAPI ns "" configmaps get, list, watch DefaultNamespaces cache informer

capi-installer

Scope API Group Resource Verbs Code evidence
ClusterRole * * get, list VAP binding paramRef fallback — when the referenced policy doesn't exist yet, the API server requires both get and list on all resources. Also covers boxcutter tracking cache reads
ClusterRole config.openshift.io infrastructures watch revision_controller.go:307 Watches()
ClusterRole config.openshift.io clusteroperators watch Informer
ClusterRole config.openshift.io clusteroperators/status update, patch related_objects.go:113, controller_status.go:295
ClusterRole operator.openshift.io clusterapis watch installer_controller.go:100, revision_controller.go:303
ClusterRole operator.openshift.io clusterapis/status update, patch revision_controller.go:234, installer_controller.go:316
ClusterRole apiextensions.k8s.io customresourcedefinitions watch, create, update, patch, delete boxcutter: provider CRDs
ClusterRole admissionregistration.k8s.io mutating/validatingwebhookconfigurations, validatingadmissionpolicies/bindings watch, create, update, patch, delete boxcutter: admission resources
ClusterRole rbac.authorization.k8s.io clusterroles watch, create, update, patch, delete, escalate, bind boxcutter: cluster RBAC. escalate/bind needed because installer creates Roles granting permissions it doesn't hold
ClusterRole rbac.authorization.k8s.io clusterrolebindings watch, create, update, patch, delete boxcutter: cluster RBAC bindings
ClusterRole various roles, rolebindings, serviceaccounts, services, deployments watch boxcutter tracking cache
Role: CAPI ns various serviceaccounts, services, deployments create, update, patch, delete boxcutter: namespace resources
Role: CAPI ns rbac.authorization.k8s.io roles create, update, patch, delete, escalate, bind boxcutter: namespace RBAC
Role: CAPI ns rbac.authorization.k8s.io rolebindings create, update, patch, delete boxcutter: namespace RBAC bindings
Role: CAPI ns cluster.x-k8s.io machines, machinesets list VAP paramRef authorization (bindings use selector: {})
Role: MAPI ns machine.openshift.io machines, machinesets list VAP paramRef authorization (bindings use selector: {})
Role: operator ns coordination.k8s.io leases get, list, watch, create, update, patch, delete Leader election
Role: operator ns "" pods get Pod self-read
Role: operator ns "" configmaps get capi-installer-images ConfigMap

Not observed by audit2rbac — justified by code or CI evidence

Scope API Group Resource Verbs Justification
ClusterRole config.openshift.io clusteroperators create operator_status.go:119 — first install only
ClusterRole rbac.authorization.k8s.io clusterroles escalate, bind Installer creates ClusterRoles (e.g. capi-manager-role) that grant permissions to CAPI provider SAs. Invisible to audit2rbac
ClusterRole * * get, list VAP binding creation when referenced policy doesn't exist yet. CI confirmed: does not have "list" permission for all groups, versions and resources
Role: operator ns apps deployments create, delete controller.go:148 SSA create on first install, :209 unsupported platform cleanup
Role: CAPI ns various boxcutter types delete Resource teardown during upgrades — no deletions during e2e

🤖 Generated with Claude Code

@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Pipeline controller notification
This repo is configured to use the pipeline controller. Second-stage tests will be triggered either automatically or after lgtm label is added, depending on the repository configuration. The pipeline controller will automatically detect which contexts are required and will utilize /test Prow commands to trigger the second stage.

For optional jobs, comment /test ? to see a list of all defined jobs. To trigger manually all jobs from second stage use /pipeline required command.

This repository is configured in: LGTM mode

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Jun 23, 2026
@openshift-ci-robot

openshift-ci-robot commented Jun 23, 2026

Copy link
Copy Markdown

@stefanonardo: This pull request references OCPCLOUD-3451 which is a valid jira issue.

Details

In response to this:

Summary

  • Replace the shared wildcard ClusterRole openshift-capi-operator (apiGroups: ['*'], resources: ['*'], verbs: ['*']) with separate, enumerated ClusterRoles for each ServiceAccount
  • capi-operator gets a narrow ClusterRole (config resources, ClusterOperator management, read-only informers) + a namespace Role (leases, Deployment write, pod self-read, events)
  • capi-installer gets a broader ClusterRole (CRDs, admission resources, cluster RBAC, tracking cache informers) + namespace Roles in openshift-cluster-api (boxcutter-managed resources, VAP paramRef), openshift-cluster-api-operator (leases, pod/configmap read), and openshift-machine-api (VAP paramRef list)
  • Derived from static code analysis of all controllers and cross-validated with audit2rbac on a live AWS cluster

Permission justification

Each rule was derived from code analysis and validated against audit2rbac output from an AWS cluster.

capi-operator — Confirmed by audit2rbac

Scope API Group Resource Verbs Code evidence
ClusterRole config.openshift.io infrastructures get main.go:104 util.GetInfra()
ClusterRole config.openshift.io clusteroperators get, list, watch, create, update, patch clusteroperator_controller.go:73, operator_status.go:119,186
ClusterRole config.openshift.io clusteroperators/status update, patch operator_status.go:186
ClusterRole config.openshift.io clusterversions, featuregates get, list, watch main.go:114 util.GetFeatureGates()
ClusterRole operator.openshift.io clusterapis get, list, watch installerdeployment/controller.go:167
ClusterRole "" configmaps get, list, watch controller.go:107,166
ClusterRole apps deployments get, list, watch controller.go:163
Role: operator ns apps deployments get, patch, update, delete controller.go:148,209
Role: operator ns "" pods get main.go:158 pod self-read
Role: operator ns "" events create, patch operator_status.go:98
Role: operator ns coordination.k8s.io leases get, list, watch, create, update, patch, delete Leader election

capi-installer — Confirmed by audit2rbac

Scope API Group Resource Verbs Code evidence
ClusterRole config.openshift.io infrastructures get, list, watch revision_controller.go:139,307
ClusterRole config.openshift.io clusteroperators get, list, watch related_objects.go:80
ClusterRole config.openshift.io clusteroperators/status get, update, patch related_objects.go:113, controller_status.go:295
ClusterRole operator.openshift.io clusterapis get, list, watch installer_controller.go:100, revision_controller.go:303
ClusterRole operator.openshift.io clusterapis/status get, update, patch revision_controller.go:234, installer_controller.go:316
ClusterRole apiextensions.k8s.io customresourcedefinitions get, list, watch, create, update, patch, delete boxcutter: provider CRDs
ClusterRole admissionregistration.k8s.io mutating/validatingwebhookconfigurations, validatingadmissionpolicies/bindings get, list, watch, create, update, patch, delete boxcutter: admission resources
ClusterRole rbac.authorization.k8s.io clusterroles, clusterrolebindings get, list, watch, create, update, patch, delete boxcutter: cluster RBAC
ClusterRole various roles, rolebindings, serviceaccounts, services, deployments get, list, watch boxcutter tracking cache
Role: CAPI ns various serviceaccounts, services, deployments, roles, rolebindings create, get, update, patch, delete boxcutter: namespace resources
Role: CAPI ns cluster.x-k8s.io machines, machinesets list VAP paramRef authorization
Role: MAPI ns machine.openshift.io machines, machinesets list VAP paramRef authorization
Role: operator ns coordination.k8s.io leases get, list, watch, create, update, patch, delete Leader election
Role: operator ns "" pods get Pod self-read
Role: operator ns "" configmaps get capi-installer-images ConfigMap

Not observed by audit2rbac — justified by code evidence

Scope API Group Resource Verbs Justification
ClusterRole config.openshift.io clusteroperators create operator_status.go:119 — first install only
Role: operator ns apps deployments delete controller.go:209 — unsupported platform cleanup (AWS is supported)
Role: operator ns "" events patch Event recorder can patch existing events
Role: CAPI ns various boxcutter types delete Resource teardown during upgrades — no deletions during e2e
Role: operator ns "" pods, configmaps get Startup-only reads — capi-installer was not restarted during audit window

🤖 Generated with Claude Code

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

RBAC rules are expanded into explicit manifest entries for capi-operator and capi-installer, with namespace-scoped Roles and matching bindings added for the required namespaces. Documentation is added for the RBAC layout and update procedure.

Changes

RBAC hardening and wiring

Layer / File(s) Summary
capi-operator rules
manifests/0000_30_cluster-api-operator_03_clusterrole.yaml
The capi-operator ClusterRole replaces wildcard access with explicit rules, and namespace-scoped Roles are added for openshift-cluster-api-operator and openshift-cluster-api.
capi-installer rules
manifests/0000_30_cluster-api-operator_03_capi-installer-clusterrole.yaml
The capi-installer ClusterRole and three namespace-scoped Roles define cluster-wide resource access and namespace-specific permissions.
RBAC bindings
manifests/0000_30_cluster-api-operator_04_clusterrolebinding.yaml, manifests/0000_30_cluster-api-operator_04_capi-installer-clusterrolebinding.yaml
RoleBindings and ClusterRoleBindings connect the capi-operator and capi-installer ServiceAccounts to the new Roles and ClusterRoles.
RBAC documentation
docs/rbac.md
RBAC documentation lists ServiceAccount-to-manifest mappings, permission scope guidance, and the RBAC update procedure.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 14 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Microshift Test Compatibility ⚠️ Warning New e2e specs use Machine/MachineSet APIs and MachineAPIMigration gating, but have no [apigroup:...], [Skipped:MicroShift], or IsMicroShiftCluster() guard. Add a MicroShift guard or tag these specs with an appropriate [apigroup:...] label (or [Skipped:MicroShift]) so MicroShift CI skips them.
✅ Passed checks (14 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: tightening capi-operator and capi-installer RBAC to least privilege.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Stable And Deterministic Test Names ✅ Passed No Ginkgo title is constructed from dynamic values; the touched e2e tests use static strings, and no It/Describe/Context/When call takes fmt.Sprintf or similar.
Test Structure And Quality ✅ Passed This PR only changes docs and RBAC manifests; no Ginkgo test files or It/Eventually code changed, so the test-structure check is not applicable.
Single Node Openshift (Sno) Test Compatibility ✅ Passed No Ginkgo e2e tests were added; the PR only changes RBAC YAML/docs, so SNO-specific test compatibility isn’t applicable.
Topology-Aware Scheduling Compatibility ✅ Passed Only RBAC/docs manifests changed; no pod specs, affinity, node selectors, replicas, topology spread, or PDBs were added.
Ote Binary Stdout Contract ✅ Passed PR only changes docs and RBAC YAML; no Go entrypoints or process-level stdout writes were added.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed The PR only adds RBAC docs/manifests; no new Ginkgo e2e tests or network/IP-handling code were introduced.
No-Weak-Crypto ✅ Passed Only RBAC docs/manifests changed; scans found no MD5/SHA1/DES/RC4/3DES/Blowfish/ECB or secret-comparison issues.
Container-Privileges ✅ Passed Changed files are docs/RBAC manifests only; no containers or pod security fields like privileged, hostNetwork, or allowPrivilegeEscalation were added.
No-Sensitive-Data-In-Logs ✅ Passed Changed files are docs/RBAC YAML only; no logging code or sensitive literals (passwords/tokens/PII) were found.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@stefanonardo

Copy link
Copy Markdown
Contributor Author

/test e2e-aws-capi-techpreview

@openshift-ci openshift-ci Bot requested review from damdo and racheljpg June 23, 2026 11:09

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
docs/rbac.md (1)

11-16: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use full, unambiguous manifest filenames in the reference table.

The table references shortened manifest names (e.g., operator_03_clusterrole.yaml, operator_03_capi-installer-clusterrole.yaml) that don't match the actual filenames in the repository. Context snippets show the full names are 0000_30_cluster-api-operator_03_clusterrole.yaml and 0000_30_cluster-api-operator_03_capi-installer-clusterrole.yaml. Developers searching the repo for the abbreviated names will not find them by exact match, reducing the documentation's usefulness for locating files. Use the full manifest names for clarity and searchability.

✏️ Suggested filename updates in the table
- | `operator_03_clusterrole.yaml` | ClusterRole `openshift-capi-operator` | cluster-wide | `capi-operator` | config.openshift.io resources, ClusterOperator management, ClusterAPI/ConfigMap/Deployment read |
- | `operator_03_clusterrole.yaml` | Role `capi-operator` | `openshift-cluster-api-operator` | `capi-operator` | Leader election leases, Deployment write (capi-installer), pod self-read, events |
- | `operator_03_capi-installer-clusterrole.yaml` | ClusterRole `openshift-capi-installer` | cluster-wide | `capi-installer` | CRDs, admission resources, cluster RBAC, config.openshift.io, ClusterAPI/ClusterOperator status, tracking cache informers |
- | `operator_03_capi-installer-clusterrole.yaml` | Role `capi-installer` | `openshift-cluster-api-operator` | `capi-installer` | Leader election leases, pod self-read, ConfigMap read, events |
- | `operator_03_capi-installer-clusterrole.yaml` | Role `capi-installer` | `openshift-cluster-api` | `capi-installer` | boxcutter-managed resources (ServiceAccounts, Services, Deployments, Roles, RoleBindings), VAP paramRef list |
- | `operator_03_capi-installer-clusterrole.yaml` | Role `capi-installer` | `openshift-machine-api` | `capi-installer` | VAP paramRef list (machines, machinesets) |
+ | `0000_30_cluster-api-operator_03_clusterrole.yaml` | ClusterRole `openshift-capi-operator` | cluster-wide | `capi-operator` | config.openshift.io resources, ClusterOperator management, ClusterAPI/ConfigMap/Deployment read |
+ | `0000_30_cluster-api-operator_03_clusterrole.yaml` | Role `capi-operator` | `openshift-cluster-api-operator` | `capi-operator` | Leader election leases, Deployment write (capi-installer), pod self-read, events |
+ | `0000_30_cluster-api-operator_03_capi-installer-clusterrole.yaml` | ClusterRole `openshift-capi-installer` | cluster-wide | `capi-installer` | CRDs, admission resources, cluster RBAC, config.openshift.io, ClusterAPI/ClusterOperator status, tracking cache informers |
+ | `0000_30_cluster-api-operator_03_capi-installer-clusterrole.yaml` | Role `capi-installer` | `openshift-cluster-api-operator` | `capi-installer` | Leader election leases, pod self-read, ConfigMap read, events |
+ | `0000_30_cluster-api-operator_03_capi-installer-clusterrole.yaml` | Role `capi-installer` | `openshift-cluster-api` | `capi-installer` | boxcutter-managed resources (ServiceAccounts, Services, Deployments, Roles, RoleBindings), VAP paramRef list |
+ | `0000_30_cluster-api-operator_03_capi-installer-clusterrole.yaml` | Role `capi-installer` | `openshift-machine-api` | `capi-installer` | VAP paramRef list (machines, machinesets) |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/rbac.md` around lines 11 - 16, Replace the shortened manifest filenames
throughout the RBAC reference table with their complete, actual repository
filenames. Update all instances of `operator_03_clusterrole.yaml` to
`0000_30_cluster-api-operator_03_clusterrole.yaml` and all instances of
`operator_03_capi-installer-clusterrole.yaml` to
`0000_30_cluster-api-operator_03_capi-installer-clusterrole.yaml` in the file
column of the table to ensure developers can locate the files through exact
repository searches.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@manifests/0000_30_cluster-api-operator_03_capi-installer-clusterrole.yaml`:
- Around line 210-237: In the capi-installer ClusterRole and Role definitions,
locate the two rule blocks for machines and machinesets resources. The first
block is under the cluster.x-k8s.io API group and the second is under the
machine.openshift.io API group. In both rule blocks, change the verbs field from
list to get, since ValidatingAdmissionPolicy paramRef authorization requires the
get verb to retrieve specific parameter resources by name rather than listing
them.

In `@manifests/0000_30_cluster-api-operator_03_clusterrole.yaml`:
- Around line 93-101: The capi-operator Role is missing the `create` verb for
the `deployments` resource in the apps apiGroup. The
InstallerDeploymentReconciler uses server-side apply which requires the `create`
verb to establish field ownership when creating resources that don't exist. Add
`create` to the verbs list for the deployments resource in the apps apiGroup
section to align with the permissions available in the capi-installer Role in
the openshift-cluster-api namespace.

---

Nitpick comments:
In `@docs/rbac.md`:
- Around line 11-16: Replace the shortened manifest filenames throughout the
RBAC reference table with their complete, actual repository filenames. Update
all instances of `operator_03_clusterrole.yaml` to
`0000_30_cluster-api-operator_03_clusterrole.yaml` and all instances of
`operator_03_capi-installer-clusterrole.yaml` to
`0000_30_cluster-api-operator_03_capi-installer-clusterrole.yaml` in the file
column of the table to ensure developers can locate the files through exact
repository searches.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: d9ad8c26-2b98-49a0-ad7a-9f2b88369977

📥 Commits

Reviewing files that changed from the base of the PR and between 5656e20 and 85634f4.

📒 Files selected for processing (5)
  • docs/rbac.md
  • manifests/0000_30_cluster-api-operator_03_capi-installer-clusterrole.yaml
  • manifests/0000_30_cluster-api-operator_03_clusterrole.yaml
  • manifests/0000_30_cluster-api-operator_04_capi-installer-clusterrolebinding.yaml
  • manifests/0000_30_cluster-api-operator_04_clusterrolebinding.yaml

Comment thread manifests/0000_30_cluster-api-operator_03_clusterrole.yaml
@stefanonardo

Copy link
Copy Markdown
Contributor Author

/test e2e-aws-capi-techpreview

@stefanonardo

Copy link
Copy Markdown
Contributor Author

/test e2e-aws-capi-techpreview

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@manifests/0000_30_cluster-api-operator_03_capi-installer-clusterrole.yaml`:
- Around line 12-19: Replace the overly permissive wildcard RBAC rule
(apiGroups: ['*'], resources: ['*'], verbs: ['get']) in the capi-installer
ClusterRole with an enumerated list of only the specific resource types that
boxcutter's manifest tracking actually requires. Remove the wildcard entirely
and instead explicitly list the minimal set of resources needed, as the
ValidatingAdmissionPolicyBinding authorization requirement is already satisfied
by existing namespace-scoped Roles that grant narrowly-scoped permissions on the
Machine paramKind from machine.openshift.io.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: e7c249ac-8be7-4767-99bc-298e8da066b1

📥 Commits

Reviewing files that changed from the base of the PR and between 18f93c0 and 1842e55.

📒 Files selected for processing (5)
  • docs/rbac.md
  • manifests/0000_30_cluster-api-operator_03_capi-installer-clusterrole.yaml
  • manifests/0000_30_cluster-api-operator_03_clusterrole.yaml
  • manifests/0000_30_cluster-api-operator_04_capi-installer-clusterrolebinding.yaml
  • manifests/0000_30_cluster-api-operator_04_clusterrolebinding.yaml
✅ Files skipped from review due to trivial changes (1)
  • docs/rbac.md
🚧 Files skipped from review as they are similar to previous changes (3)
  • manifests/0000_30_cluster-api-operator_03_clusterrole.yaml
  • manifests/0000_30_cluster-api-operator_04_capi-installer-clusterrolebinding.yaml
  • manifests/0000_30_cluster-api-operator_04_clusterrolebinding.yaml

Comment thread manifests/0000_30_cluster-api-operator_03_capi-installer-clusterrole.yaml Outdated
@stefanonardo

Copy link
Copy Markdown
Contributor Author

/test e2e-aws-capi-techpreview

Comment on lines +53 to +60
- apiGroups:
- ""
resources:
- configmaps
verbs:
- get
- list
- watch

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any idea what this is for? Suspect it only needs 1 CM in the -operator namespace. Would be good to pin this down a bit.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, only capi-installer-images is used. I moved configamaps into namespace Roles.

Comment on lines +18 to +21
- apiGroups:
- config.openshift.io
resources:
- clusteroperators

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we restrict create/update/patch to just its own CO, by name?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done. create can't be restricted by name because the object does not exist yet and list/watch do not support resourceNames

Comment on lines +61 to +68
- apiGroups:
- apps
resources:
- deployments
verbs:
- get
- list
- watch

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it need this? I see it has permissions to create its specific deployment in -operator below.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as configmaps

@mdbooth

mdbooth commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

/approve

But please address comments before committing.

@openshift-ci

openshift-ci Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: mdbooth

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jun 25, 2026
@stefanonardo

Copy link
Copy Markdown
Contributor Author

/test e2e-aws-capi-techpreview

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
manifests/0000_30_cluster-api-operator_03_capi-installer-clusterrole.yaml (1)

91-105: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Scope bind/escalate to role resources only.

bind and escalate are special RBAC permissions for roles/clusterroles; binding objects only need their normal CRUD verbs. Splitting these rules keeps the required installer behavior while avoiding unnecessary special verbs on rolebindings/clusterrolebindings. (kubernetes.io)

As per path instructions, “RBAC: least privilege; no cluster-admin for workloads.”

Suggested RBAC split
 - apiGroups:
   - rbac.authorization.k8s.io
   resources:
   - clusterroles
-  - clusterrolebindings
   verbs:
   - get
   - list
   - watch
   - create
   - update
   - patch
   - delete
   - escalate
   - bind
+- apiGroups:
+  - rbac.authorization.k8s.io
+  resources:
+  - clusterrolebindings
+  verbs:
+  - get
+  - list
+  - watch
+  - create
+  - update
+  - patch
+  - delete
 - apiGroups:
   - rbac.authorization.k8s.io
   resources:
   - roles
-  - rolebindings
   verbs:
   - create
   - get
   - update
   - patch
   - delete
   - escalate
   - bind
+- apiGroups:
+  - rbac.authorization.k8s.io
+  resources:
+  - rolebindings
+  verbs:
+  - create
+  - get
+  - update
+  - patch
+  - delete

Also applies to: 210-222

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@manifests/0000_30_cluster-api-operator_03_capi-installer-clusterrole.yaml`
around lines 91 - 105, The RBAC rule in the installer ClusterRole is granting
bind and escalate alongside normal CRUD verbs for both roles and binding
resources, which is too broad. Update the ClusterRole manifest so the special
verbs are scoped only to the roles/clusterroles rules, and keep
rolebindings/clusterrolebindings limited to standard
get/list/watch/create/update/patch/delete access. Use the existing RBAC rule
block in the installer ClusterRole as the place to split these permissions.

Sources: Path instructions, Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@manifests/0000_30_cluster-api-operator_03_capi-installer-clusterrole.yaml`:
- Around line 91-105: The RBAC rule in the installer ClusterRole is granting
bind and escalate alongside normal CRUD verbs for both roles and binding
resources, which is too broad. Update the ClusterRole manifest so the special
verbs are scoped only to the roles/clusterroles rules, and keep
rolebindings/clusterrolebindings limited to standard
get/list/watch/create/update/patch/delete access. Use the existing RBAC rule
block in the installer ClusterRole as the place to split these permissions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 2f198517-9f40-4f56-8e7b-f034099c22e7

📥 Commits

Reviewing files that changed from the base of the PR and between 1842e55 and c7a1ea4.

📒 Files selected for processing (5)
  • docs/rbac.md
  • manifests/0000_30_cluster-api-operator_03_capi-installer-clusterrole.yaml
  • manifests/0000_30_cluster-api-operator_03_clusterrole.yaml
  • manifests/0000_30_cluster-api-operator_04_capi-installer-clusterrolebinding.yaml
  • manifests/0000_30_cluster-api-operator_04_clusterrolebinding.yaml
✅ Files skipped from review due to trivial changes (1)
  • docs/rbac.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • manifests/0000_30_cluster-api-operator_04_capi-installer-clusterrolebinding.yaml

@mdbooth

mdbooth commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Jun 25, 2026
@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Scheduling tests matching the pipeline_run_if_changed or not excluded by pipeline_skip_if_only_changed parameters:
/test e2e-aws-ovn
/test e2e-aws-ovn-serial-1of2
/test e2e-aws-ovn-serial-2of2
/test e2e-aws-capi-disconnected-techpreview
/test e2e-aws-capi-techpreview
/test e2e-aws-capi-techpreview-post-install
/test e2e-aws-ovn-techpreview
/test e2e-aws-ovn-techpreview-upgrade
/test e2e-azure-capi-techpreview
/test e2e-azure-ovn-techpreview
/test e2e-azure-ovn-techpreview-upgrade
/test e2e-gcp-capi-techpreview
/test e2e-gcp-ovn-techpreview
/test e2e-metal3-capi-techpreview
/test e2e-openstack-capi-techpreview
/test e2e-vsphere-capi-techpreview
/test regression-clusterinfra-aws-ipi-techpreview-capi

Replace the shared wildcard ClusterRole with separate, enumerated
RBAC for each ServiceAccount. Validated with audit2rbac and e2e
tests on an AWS cluster.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@openshift-ci openshift-ci Bot removed the lgtm Indicates that a PR is ready to be merged. label Jun 26, 2026
@stefanonardo

Copy link
Copy Markdown
Contributor Author

/test e2e-aws-capi-techpreview

@stefanonardo

Copy link
Copy Markdown
Contributor Author

/test e2e-aws-capi-techpreview

@mdbooth

mdbooth commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Jun 29, 2026
@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Tests from second stage were triggered manually. Pipeline can be controlled only manually, until HEAD changes. Use command to trigger second stage.

@damdo

damdo commented Jul 1, 2026

Copy link
Copy Markdown
Member

/pipeline required

@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Scheduling tests matching the pipeline_run_if_changed or not excluded by pipeline_skip_if_only_changed parameters:
/test e2e-aws-ovn
/test e2e-aws-ovn-serial-1of2
/test e2e-aws-ovn-serial-2of2
/test e2e-aws-capi-disconnected-techpreview
/test e2e-aws-capi-techpreview
/test e2e-aws-capi-techpreview-post-install
/test e2e-aws-ovn-techpreview
/test e2e-aws-ovn-techpreview-upgrade
/test e2e-azure-capi-techpreview
/test e2e-azure-ovn-techpreview
/test e2e-azure-ovn-techpreview-upgrade
/test e2e-gcp-capi-techpreview
/test e2e-gcp-ovn-techpreview
/test e2e-metal3-capi-techpreview
/test e2e-openstack-capi-techpreview
/test e2e-vsphere-capi-techpreview
/test regression-clusterinfra-aws-ipi-techpreview-capi

@openshift-ci

openshift-ci Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

@stefanonardo: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/e2e-metal3-capi-techpreview 55b154a link false /test e2e-metal3-capi-techpreview
ci/prow/e2e-aws-ovn-techpreview 55b154a link true /test e2e-aws-ovn-techpreview
ci/prow/e2e-aws-capi-techpreview 55b154a link true /test e2e-aws-capi-techpreview
ci/prow/e2e-aws-ovn-techpreview-upgrade 55b154a link true /test e2e-aws-ovn-techpreview-upgrade
ci/prow/regression-clusterinfra-aws-ipi-techpreview-capi 55b154a link false /test regression-clusterinfra-aws-ipi-techpreview-capi
ci/prow/e2e-aws-capi-techpreview-post-install 55b154a link true /test e2e-aws-capi-techpreview-post-install
ci/prow/e2e-azure-ovn-techpreview-upgrade 55b154a link true /test e2e-azure-ovn-techpreview-upgrade
ci/prow/e2e-gcp-ovn-techpreview 55b154a link true /test e2e-gcp-ovn-techpreview

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. lgtm Indicates that a PR is ready to be merged.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants